package com.bluesky.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;

@Configuration
public class ThreadPoolConfig {

    /*
    public ThreadPoolExecutor(int corePoolSize,//核心线程数
                          int maximumPoolSize,//最大线程数
                          long keepAliveTime,//线程空闲时间
                          TimeUnit unit,//时间单位
                          BlockingQueue<Runnable> workQueue,//任务队列
                          ThreadFactory threadFactory,//线程工厂
                          RejectedExecutionHandler handler//拒绝策略)
                          {
                          }

    ThreadPoolTaskExecutor是Spring框架中用于管理线程池的一个组件，它基于JDK的ThreadPoolExecutor实现，并提供了一些额外的功能。
     以下是ThreadPoolTaskExecutor的主要参数及其作用：

    corePoolSize：线程池维护线程的最小数量。当线程池中的线程数少于corePoolSize时，线程工厂会创建新线程来处理任务。
    maximumPoolSize：线程池维护线程的最大数量。当线程池中的线程数达到maximumPoolSize时，拒绝策略将决定如何处理新任务。
    keepAliveTime：空闲线程的存活时间。当线程池中的线程数量超过corePoolSize时，多余的空闲线程在等待新任务的时间超过keepAliveTime后将被终止。
    unit：时间单位，用于指定keepAliveTime的时间单位，如纳秒、微秒、毫秒、秒等。
    workQueue：持有等待执行的任务的队列。当所有线程都在忙时，新任务将被放入该队列等待执行。
    threadFactory：用于设置创建线程的工厂，可以通过线程工厂给每个创建出来的线程设置更有意义的名字。
    rejectedExecutionHandler：拒绝策略，当队列workQueue和线程池maxPoolSize都满了，说明线程池处于饱和状态，此时必须采取一种策略处理提交的新任务。常见的拒绝策略包括：
    AbortPolicy：丢弃任务并抛出RejectedExecutionException异常。
    DiscardPolicy：丢弃任务但不抛出异常。
    CallerRunsPolicy：直接在execute方法的调用线程中运行被拒绝的任务。
    DiscardOldestPolicy‌：丢弃队列中最前面的任务，然后重新尝试执行任务。
    这些参数共同决定了线程池的行为和性能，合理配置这些参数可以提高应用程序的效率和稳定性。
    */
    @Bean
    public ThreadPoolTaskExecutor threadPoolExecutor(){
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setThreadNamePrefix("ThreadPool-Goods-");
        // 线程池  核心线程数为cpu核数 * 4，
        threadPoolTaskExecutor.setCorePoolSize(Runtime.getRuntime().availableProcessors()*4);
        //最大线程数据为cpu核数 * 8
        threadPoolTaskExecutor.setMaxPoolSize(Runtime.getRuntime().availableProcessors()*8);
        // 队列容量为0，则任务就不会进入队列
        threadPoolTaskExecutor.setQueueCapacity(0);
        // 拒绝策略使用CallerRunsPolicy，让当前线程去兜底去执行任务
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return threadPoolTaskExecutor;

    }


    public static void main(String[] args) {
        SynchronousQueue<String> queue = new SynchronousQueue<>();

        System.out.println(queue.offer("abd"));
    }


}

/*

https://blog.csdn.net/m0_62943934/article/details/134898940
https://blog.csdn.net/mythsmyths/article/details/131961323

ThreadPoolExecutor
ThreadPoolExecutor 类可以非常方便地创建线程池对象，而不需要程序员设计大量的 new 实例化 Thread 相关的代码。

前面使用 Executors 类中的 newXXXThreadExecutor() 方法可以快速地创建线程池，但创建的细节未知，
因为已经被封装处理，查看 newSingleThreadExecutor() 方法时，其内部其实实例化了一个 ThreadPoolExecutor 类的实例，源代码如下：
     public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

    ThreadPoolExecutor 类参数最全的构造方法如下：

参数解释如下：

corePoolSize：池中至少要保留的线程数，该属性就是定义 corePool 核心池的大小。
maximumPoolSize：池中允许的最大线程数，maximumPoolSize 包含 corePoolSize。
keepAliveTime：当线程数量大于 corePoolSize 值时，在没有超过指定的时间内是不能从线程池中将空闲的线程删除的，如果超过此时间单位，则删除空闲线程。为 0 时，执行完任务立即删除此线程。”能删除的空闲线程“范围是 maximumPoolSize ~ corePoolSize，也就是 corePoolSize 之外的线程。
unit：keepAliveTime 参数的时间单位。
workQueue：执行前用于保持任务的队列。此队列仅保持由 execute 方法提交的任务。使用 ThreadPoolExecutor 类时一般会传入 LinkedBlockingQueue 和 SynchronousQueue 这两个队列。
threadFactory：创建线程的工厂，可以是自定义的。
handler：是一个接口类型，用来指定当任务被拒绝执行时的处理策略。当线程池已经达到了最大线程数，且工作队列也已经满了的时候，如果还有新的任务提交到线程池，这些任务会被拒绝。在这种情况下，RejectedExecutionHandler 对象就会被调用。
注意，所谓的空闲线程就是没有执行任务的线程，不管这个线程在哪里，只要不执行任务，它就是空闲的。
* */